// 生成数独解决方案
const Toolkit = require("./toolkit")

module.exports = class Generator {
	generate() {
		while(!this.internalGenerate()) {
			console.warn("try again")
		}
		return this.matrix;
	}
	internalGenerate() {
		
		this.matrix = Toolkit.matrix.makeMatrix();
		
		this.orders = Array.from({ length: 9 })
				.map(() => Array.from({ length: 9 }, (x, i) => i))
				.map(row => Toolkit.matrix.shuffle(row));

		return Array.from({ length: 9 })
				.every((n, i) => this.fillNumber(i + 1));
	}
	fillNumber(n) {
		return this.fillRow(n, 0)
	}
	fillRow(n, rowIndex) {
		if(rowIndex > 8) return true
		
		const row = this.matrix[rowIndex]
		const orders = this.orders[rowIndex]
		// TODO 随机选择列
		for(let i=0; i<orders.length; i++){
			const colIndex = orders[i]
			// const colIndex = i
			// 如果这个位置已经有值，跳过
			if(row[colIndex]) continue
			
			// 检查这个位置是否可以填n
			// TODO toolkit.matrix.checkFillable()
			if(!Toolkit.matrix.checkFillable(this.matrix, n, rowIndex, colIndex)) continue
			
			row[colIndex] = n
			
			// 当前填写n成功，递归调用fillRow()来在下一行中填写n
			// 填写失败，就继续寻找当前行下一个位置
			if(!this.fillRow(n, rowIndex+1)) {
				row[colIndex] = 0
				continue
			}
			return true
		}
		return false
	}
}

// const generator = new Generator()
// generator.generate()
// console.log(generator.matrix)
